﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "WeakReferenceable.h"
#include "IType.h"
#include "ElementCreationOptions.h"

namespace gcmp
{
    class IDocument;
    class IInstance;
    class IFamily;

    /// \brief 构件类型对象接口
    class GCMP_MODEL_INTERFACE_EXPORT IInstanceType : public IType
    {
        DEFINE_CAST_DERIVED(gcmp::IInstanceType, gcmp::IType);
    public:

        /// \brief 获得所属族Id
        /// \return 所属族Id
        virtual ElementId GetFamilyId() const = 0;

        /// \brief 获得所属族
        /// \return 所属族指针
        virtual IFamily* GetFamily() const = 0;

        /// \brief 获得该类型的所有构建对象
        /// \return 该类型的所有构建对象
        virtual std::vector<IInstance*> GetAllInstances() const = 0;

        /// \brief 创建该类型的构件实例对象
        /// \param name 实例名称
        /// \param canBeShared 对象是否可以共享
        /// \param elementCreationOptions 对象创建方式
        /// \param bCreateGeometryRelationshipComponent 是否创建默认几何关系组件
        /// \return 创建的实例对象
        virtual IInstance* CreateInstance(const std::wstring& name, bool canBeShared = true, ElementCreationOptions elementCreationOptions = ElementCreationOptions::Normal, bool bCreateGeometryRelationshipComponent = true) const = 0;

        /// \brief 此实例类型的改动影响范围是否是全局的
        /// \return true - 影响整个项目内所有此类型的构件；false - 影响部分构件
        virtual bool IsGlobal() const = 0;

        /// \brief 此实例类型是否为嵌套构件子构件实例类型
        /// \return true - 是子构件实例类型；false - 不是子构件实例类型
        virtual bool IsSub() const = 0;

        /// \brief 获得顶层构件Id
        /// 
        ///  如果该实例类型为嵌套构件子构件实例类型，则可通过该接口获得顶层构件的ElementId
        ///  如果该实例类型并不是嵌套构件子构件实例类型，则返回无效ElementId
        /// \return 所属顶层构件Id
        virtual const ElementId& GetTopFamilyId() const = 0;

        /// \brief 获得所属构件在主构件中的Id路径
        /// 
        ///  如果该实例类型为嵌套构件子构件实例类型，则可通过该接口获得所属构件在主构件中的Id路径
        ///  如果该实例类型并不是嵌套构件子构件实例类型，则返回空路径
        /// \return 所属顶层构件Id
        virtual const std::vector<Int64>& GetSubFamilyIdPath() const = 0;

    public:
        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();
    };
}
